package com.youmu.shop.order.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.ContextLoader;

import com.exception.ParamException;
import com.result.Result;
import com.result.ResultUtils;
import com.youmu.shop.admin.dao.AdminDao;
import com.youmu.shop.admin.service.AdminService;
import com.youmu.shop.biz.bean.DispatchingParam;
import com.youmu.shop.common.utils.ConfigUtil;
import com.youmu.shop.common.utils.KdniaoUtil;
import com.youmu.shop.context.utils.UserContext;
import com.youmu.shop.http.utils.HttpUtil;
import com.youmu.shop.json.utils.JacksonUtil;
import com.youmu.shop.order.bean.OrderBean;
import com.youmu.shop.order.bean.OrderItemBean;
import com.youmu.shop.order.service.OrderService;
import com.youmu.shop.order.vo.OrderDetailVo;
import com.youmu.shop.order.vo.OrderVo;
import com.youmu.shop.order.vo.ShippingMethodVo;
import com.youmu.shop.param.CalculateFreightParam;
import com.youmu.shop.system.bean.Admin;
import com.youmu.shop.weixin.vo.WeixinInfo;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;


@RestController
@RequestMapping(value = "/order/remote/")
public class OrderController {
    
	@Resource
    private OrderService orderService;
    
    @Autowired
    private AdminService adminService;
    
    @Autowired
    private AdminDao adminDao;
    
    @ApiOperation(value = "根据订单类型查询订单")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "orderStatus", value = "订单状态(0-待支付 ，自营：1已支付，2配送中，5待评价，6已完成；快递：1已支付，3待发货，4已发货，5待评价，6已完成;  7-已取消)", required = false, dataType = "Integer", paramType = "query"),
        @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "Long", paramType = "query") 
    })
    @RequestMapping(value = "findOrderByStatus",method=RequestMethod.GET)
    public Result<OrderVo> findOrderByStatus(Integer orderStatus,Long userId) {
        if(userId == null){
            throw new ParamException("用户id为空");
        }
//        List<OrderVo>  orderVOs = orderService.findOrderByStatus(orderStatus,userId);
        List<OrderVo>  orderVOs = orderService.findOrderByStatus(orderStatus,userId);
        Long nowTime = new Date().getTime();
        List<OrderVo> returnList = new ArrayList<OrderVo>();
        for (OrderVo orderVo : orderVOs) {
        	if(orderVo.getOrderStatus() == 0){
        		if(( (nowTime - orderVo.getCreateDate().getTime()) / (1000 * 60)) < 30 ){
        			returnList.add(orderVo);
        		}
        	}else{
        		returnList.add(orderVo);
        	}
		}
        return ResultUtils.createDefResult(returnList);
    }
    
    @ApiOperation(value = "查询订单详情")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "orderId", value = "订单id", required = true, dataType = "Long", paramType = "query") 
    })
    @RequestMapping(value = "findOrderDetail",method=RequestMethod.GET)
    public Result<OrderVo> findOrderDetail(Long orderId) {
    if(orderId == null){
        throw new ParamException("订单id不能为空");
    }
        OrderDetailVo detailVo = orderService.findOrderDetail(orderId);
        detailVo.setNowTime(System.currentTimeMillis());
        return ResultUtils.createDefResult(detailVo);
    }
    
    @ApiOperation(value = "下单")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "member", value = "用户id", required = true, dataType = "Long", paramType = "query"),
        @ApiImplicitParam(name = "receiveId", value = "收件地址id", required = true, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "sendTime", value = "配送时间(日期+时间段)", required = false, dataType = "Long", paramType = "query"),
        @ApiImplicitParam(name = "sendEndTime", value = "配送截止时间(格式为 HH：mm)", required = false, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "shippingMethod", value = "配送方式id", required = false, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "orderItemBeans[0].thumbnail", value = "商品项图片", required = false, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "orderItemBeans[0].name", value = "商品项名称", required = false, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "orderItemBeans[0].sendType", value = "配送类型", required = false, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "orderItemBeans[0].intro", value = "商品项备注", required = false, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "orderItemBeans[0].quantity", value = "商品项数量", required = false, dataType = "Integer", paramType = "query"),
        @ApiImplicitParam(name = "orderItemBeans[0].price", value = "商品项价格", required = false, dataType = "Double", paramType = "query"),
        @ApiImplicitParam(name = "orderItemBeans[0].productId", value = "商品项商品id", required = false, dataType = "Long", paramType = "query"),
        @ApiImplicitParam(name = "orderItemBeans[0].cartId", value = "购物车id", required = false, dataType = "Long", paramType = "query"),
        @ApiImplicitParam(name = "intro", value = "订单备注", required = false, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "couponCode", value = "优惠券id", required = false, dataType = "Long", paramType = "query"),
        @ApiImplicitParam(name = "shopingPoint", value = "积分抵扣", required = false, dataType = "Integer", paramType = "query"),
        @ApiImplicitParam(name = "totalQuality", value = "订单商品数量总计", required = true, dataType = "Integer", paramType = "query"),
        @ApiImplicitParam(name = "freight", value = "运费", required = false, dataType = "Double", paramType = "query"),
        @ApiImplicitParam(name = "totalAmount", value = "订单总金额", required = true, dataType = "Double", paramType = "query"),
        @ApiImplicitParam(name = "amountPaid", value = "实付款", required = true, dataType = "Double", paramType = "query"),
        @ApiImplicitParam(name = "toolPrice", value = "实付款", required = true, dataType = "Double", paramType = "query")
    })
    @RequestMapping(value = "createOrder",method=RequestMethod.POST)
    public Result<Long> createOrder(OrderBean orderBean) {
        if(orderBean == null){
            throw new ParamException("order不能为空");
        }
        if(orderBean.getMember() == null){
            throw new ParamException("用户不能为空");
        }
        if(orderBean.getReceiveId() == null){
            throw new ParamException("收件人信息不能为空");
        }
        if(orderBean.getTotalQuality() == null){    
            throw new ParamException("商品数量不能为空");
        }
        long orderId = orderService.createOrder(orderBean);
        return ResultUtils.createDefResult(orderId);
    }
    
    @ApiOperation(value = "根据地址获取运费")
    @RequestMapping(value = "getFreightByAddress",method=RequestMethod.GET)
    @ApiImplicitParams({
        @ApiImplicitParam(name = "address", value = "用户地址", required = true, dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "endTime", value = "最晚配送时间", required = true, dataType = "String", paramType = "query")
    })
    public Result<Double> getFreightByAddress(String address,String endTime){
        if(StringUtils.isBlank(address)){
            throw new ParamException("地址不能为空");
        }
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("address", address);
        params.put("time", endTime);
        String postHttp = HttpUtil.postHttp(ConfigUtil.getCalculateFreightUrl(), params);
        Map json2Map = JacksonUtil.JSON2Map(postHttp);
        Double freight = (Double) json2Map.get("freight");
        return ResultUtils.createDefResult(freight);
    }
    
    @ApiOperation(value = "可用积分抵扣")
    @RequestMapping(value = "getShopingPointByUserId",method=RequestMethod.GET)
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "Long", paramType = "query")
    })
    public Result<Double> getShopingPointByUserId(Long userId){
        if(userId == null){
            throw new ParamException("用户不能为空");
        }
        double result = orderService.getShopingPointByUserId(userId);
        return ResultUtils.createDefResult(result);
    }
    
    @ApiOperation(value = "微信支付")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "orderId", value = "订单Id", required = true,paramType="query", dataType = "long"),
        @ApiImplicitParam(name = "amount", value = "支付金额", required = true,paramType="query", dataType = "double")
    })
    @RequestMapping(value = "payWeixin", method = RequestMethod.POST)
    public Result<WeixinInfo> payWeixin(HttpServletRequest request,Long orderId,Double amount) {
        if(amount == null){
            throw new ParamException("金额不能为空");
        }
        if(orderId == null){
            throw new ParamException("orderId不能为空");
        }
        
        return ResultUtils.createDefResult(orderService.payWeixin(orderId,amount,request.getRemoteAddr()));
    }
    
    @ApiOperation(value = "微信支付回调")
    @RequestMapping(value = "notifyWeixin", method = RequestMethod.POST)
    public String notifyWeixin(HttpServletRequest request,@RequestBody String body) {
        return orderService.notifyWeixin(body);
       
    }
    
    @SuppressWarnings("unchecked")
	@ApiOperation(value = "取消订单")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "订单Id", required = true,paramType="query", dataType = "long")
    })
    @RequestMapping(value = "cancelOrder",method=RequestMethod.POST)
    public Result<Long> cancelOrder(Long id) {
        if(id == null){
            throw new ParamException("id不能为空");
        }
        
        orderService.cancelOrder(id);
        return ResultUtils.createNullResult();
    }
    
    @SuppressWarnings("unchecked")
	@ApiOperation(value = "查看快递物流")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "sendType", value = "选择运送方式(YTO圆通；SF顺丰)", required = true,paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "orderId", value = "订单id", required = true,paramType="query", dataType = "String")
    })
    @RequestMapping(value = "findExpress",method=RequestMethod.POST)
    public Result<Long> findExpress(String sendType,Long orderId) {
        if(StringUtils.isBlank(sendType)){
            throw new ParamException("运送方式不能为空");
        }
        if(orderId == null){
            throw new ParamException("订单号不能为空");
        }
        if(!sendType.equals("SF") && !sendType.equals("YTO")){
            throw new ParamException("未找到对应物流公司，请检查运送方式");
        }
        JSONObject result = null;
        try {
            String outSn = orderService.getShippingByOrderId(orderId);
            result = KdniaoUtil.getInstance().getOrderTracesByJson(sendType, outSn);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtils.createDefResult(result);
    }
    
    
    @SuppressWarnings("rawtypes")
	@ApiOperation(value = "获取再次购买中的订单项")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "orderId", value = "订单id", required = true,paramType="query", dataType = "Long")
    })
    @RequestMapping(value = "getBuyAgainItems",method=RequestMethod.POST)
    public Result getBuyAgainItems(Long orderId) {
        if(orderId == null){
            throw new ParamException("订单号不能为空");
        }
        
        List<OrderItemBean> buyAgains = orderService.getBuyAgain(orderId);
        return ResultUtils.createDefResult(buyAgains);
    }
    
    @SuppressWarnings("rawtypes")
	@ApiOperation(value = "根据订单id和用户id获取实付款")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "orderId", value = "订单id", required = true,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "userId", value = "用户id", required = true,paramType="query", dataType = "Long")
    })
    @RequestMapping(value = "getPaidAmountByInfo",method=RequestMethod.POST)
    public Result getPaidAmountByInfo(Long orderId,Long userId) {
        if(orderId == null){
            throw new ParamException("订单号不能为空");
        }
        if(userId == null){
            throw new ParamException("用户不能为空");
        }
        
//        Double paidAmount = orderService.getPaidAmountByInfo(orderId,userId);
        Double paidAmount = orderService.getPaidAmountByInfo(orderId,userId);
        return ResultUtils.createDefResult(paidAmount);
    }
    
    @SuppressWarnings("rawtypes")
	@ApiOperation(value = "选择配送方式")
    @RequestMapping(value = "getShippingMethod",method=RequestMethod.GET)
    public Result getShippingMethod() {
        List<ShippingMethodVo> methodVo = orderService.getShippingMethod();
        return ResultUtils.createDefResult(methodVo);
    }
    
    
    @ApiOperation(value = "配送端首页加载")
    @RequestMapping(value = "dispatchingForAdmin", method = RequestMethod.GET)
    public Result dispatchingForAdmin(HttpServletRequest request, Integer orderStatus, @RequestParam(value = "currentPage")Integer currentPage){
    	Admin admin = adminService.checkAdminDispatchingType(UserContext.getAdminInfo());
    	 if(admin == null){
             throw new ParamException("当前用户未登录");
         }
//    	if(currentPage == null){
//    		throw new ParamException("当前页数为空");
//    	}
    	 Map<String, Object> returnMap = new HashMap<>();
    	 if(orderStatus == null){
    		 switch (admin.getDispatchingType()) {
			case 1:
				orderStatus = 1;
				break;
			default:
				orderStatus = 3;
				break;
			}
    	 }
    	 returnMap.put("list", orderService.selectOrdersForDispatchingAdmin(admin, orderStatus,currentPage));
    	 returnMap.put("admin", admin);
    	return ResultUtils.createDefResult(returnMap);
    }

    @ApiOperation(value = "配送端订单状态改变操作")
    @RequestMapping(value = "orderTaking", method = RequestMethod.POST)
    public Object orderTaking(@RequestBody DispatchingParam dispatchingParam){
    	Admin admin = UserContext.getAdminInfo();
    	dispatchingParam.setPosterId(admin.getId());
    	orderService.orderTaking(ContextLoader.getCurrentWebApplicationContext().getServletContext() ,dispatchingParam, admin);
    	return ResultUtils.createDefResult(null);
    }
    
    @ApiOperation(value = "配送端订单状态改变操作")
    @RequestMapping(value = "orderFinish", method = RequestMethod.POST)
    public Object orderFinish(@RequestBody DispatchingParam dispatchingParam){
    	orderService.orderFinish(ContextLoader.getCurrentWebApplicationContext().getServletContext() ,dispatchingParam, null);
    	return ResultUtils.createDefResult(null);
    }
    
    @ApiOperation(value = "查询我的工单，或自营(闪送)中送单页面订单")
    @RequestMapping(value = "selectDispatchingByAdmin", method = RequestMethod.GET)
    public Object selectDispatchingByAdmin(HttpServletRequest request, Integer orderStatus, Integer currentPage){
    	Admin admin = adminService.checkAdminDispatchingType(UserContext.getAdminInfo());
    	Map<String, Object> returnMap = new HashMap<>();
   	 	returnMap.put("list", orderService.selectDispatchingByAdmin(admin, orderStatus, currentPage));
   	 	returnMap.put("admin", admin);
   	 	return ResultUtils.createDefResult(returnMap);
    }
    
    /**
     * 根据商品类型和收货人地址计算出运费
     * @return
     * @throws Exception 
     */
    @RequestMapping(value = "calculateFreightByProductTypeAndReceiverAddress", method = RequestMethod.POST)
    public Object calculateFreightByProductTypeAndReceiverAddress(CalculateFreightParam calculateFreightParam) throws Exception{
    	return ResultUtils.createDefResult(orderService.calculateFreightByProductTypeAndReceiverAddress(calculateFreightParam));
    }
    
    /**
     * 确认收货
     * @return
     */
    @RequestMapping(value = "confirmReceipt", method = RequestMethod.POST)
    public Object confirmReceipt(Long orderId){
    	return ResultUtils.createDefResult(orderService.confirmReceipt(orderId));
    }
}
